#ifndef _Ape_EventModel_Event_h
#define _Ape_EventModel_Event_h

#include <Ape/Object.h>
#include <Ape/EventModel/EventCallback.h>
#include <Ape/Collections/Queue.h>

namespace Ape {
	namespace EventModel {
	
		template <class EventArgs_t>
		class Event : public Object {
			TYPE_NAME ("Ape::EventModel::Event")
		private:
			Ape::Collections::Queue<EventCallback_Base*> m_Callbacks;
		public:
			Event();
			virtual ~Event();
			
			void operator += (EventCallback_Base* cb);
			void operator () (EventArgs_t& ea);
		};
		
		
		// ---------------------------------------------------------- //
		template <class EventArgs_t>
		Event<EventArgs_t>::Event() {
		
		}
		template <class EventArgs_t>
		Event<EventArgs_t>::~Event() {
			while (m_Callbacks.get_Count() ) {
				m_Callbacks.Deq()->Leave();
			}
		}
		
		template <class EventArgs_t>
		void Event<EventArgs_t>::operator += (EventCallback_Base* cb) {
			cb->TakeCare();
			m_Callbacks.Enq (cb);
		}
		template <class EventArgs_t>
		void Event<EventArgs_t>::operator () (EventArgs_t& ea) {
			size_t iCount = m_Callbacks.get_Count();
			for (size_t i = 0; i < iCount; i++) {
				EventCallback_Base* cb = m_Callbacks.Deq();
				(*cb) (ea);
				m_Callbacks.Enq (cb);
				if (ea.Cancelled() )
					break;
			}
		}
		
		typedef Event<Ape::EventModel::EventArgs> GenericEvent;
	}
}

#endif // _Ape_EventModel_Event_h
